//! 服务器端核心组件综合测试
//! 
//! 为配置服务器的核心trait接口提供全面的Mock测试

use crate::core::*;
use crate::RustCloudConfig;
use std::collections::HashMap;
use std::time::{Duration, SystemTime};
use std::sync::Arc;
use tokio::sync::RwLock;
use async_trait::async_trait;

#[cfg(test)]
mod server_core_tests {
    use super::*;

    /// Mock服务错误类型
    #[derive(Debug)]
    pub enum MockServiceError {
        NotFound(String),
        StorageError(String),
    }

    impl std::fmt::Display for MockServiceError {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            match self {
                MockServiceError::NotFound(msg) => write!(f, "配置不存在: {}", msg),
                MockServiceError::StorageError(msg) => write!(f, "存储错误: {}", msg),
            }
        }
    }

    impl std::error::Error for MockServiceError {}

    // ============ Mock存储组件 ============

    pub struct AdvancedMockStorage {
        data: Arc<RwLock<HashMap<String, ConfigurationData>>>,
        should_fail: bool,
    }

    impl AdvancedMockStorage {
        pub fn new() -> Self {
            Self {
                data: Arc::new(RwLock::new(HashMap::new())),
                should_fail: false,
            }
        }

        pub fn with_failure() -> Self {
            Self {
                data: Arc::new(RwLock::new(HashMap::new())),
                should_fail: true,
            }
        }

        async fn make_key(&self, env: &ConfigEnvironment) -> String {
            format!("{}:{}:{}", env.application, env.profile, env.label)
        }

        pub async fn add_test_data(&self, env: ConfigEnvironment, config: RustCloudConfig) {
            let key = self.make_key(&env).await;
            let data = ConfigurationData {
                environment: env,
                config,
                version: "v1.0.0".to_string(),
                last_modified: SystemTime::now(),
                source: "test".to_string(),
                properties: HashMap::new(),
            };
            self.data.write().await.insert(key, data);
        }
    }

    #[async_trait]
    impl ConfigurationStorage for AdvancedMockStorage {
        async fn load(&self, environment: &ConfigEnvironment) -> ConfigurationResult<ConfigurationData> {
            if self.should_fail {
                return Err(Box::new(MockServiceError::StorageError("模拟存储失败".to_string())));
            }

            let key = self.make_key(environment).await;
            let data = self.data.read().await;
            
            match data.get(&key) {
                Some(config_data) => Ok(config_data.clone()),
                None => Err(Box::new(MockServiceError::NotFound(format!("配置不存在: {}", key)))),
            }
        }

        async fn save(&self, data: &ConfigurationData, _user: &str) -> ConfigurationResult<String> {
            if self.should_fail {
                return Err(Box::new(MockServiceError::StorageError("模拟保存失败".to_string())));
            }

            let key = self.make_key(&data.environment).await;
            let mut stored_data = data.clone();
            stored_data.version = "v1.0.1".to_string();
            
            self.data.write().await.insert(key, stored_data);
            Ok("v1.0.1".to_string())
        }

        async fn delete(&self, environment: &ConfigEnvironment, _user: &str) -> ConfigurationResult<()> {
            if self.should_fail {
                return Err(Box::new(MockServiceError::StorageError("模拟删除失败".to_string())));
            }

            let key = self.make_key(environment).await;
            self.data.write().await.remove(&key);
            Ok(())
        }

        async fn get_history(&self, _environment: &ConfigEnvironment) -> ConfigurationResult<Vec<ConfigurationChange>> {
            if self.should_fail {
                return Err(Box::new(MockServiceError::StorageError("模拟历史查询失败".to_string())));
            }

            Ok(vec![
                ConfigurationChange {
                    id: "change-1".to_string(),
                    environment: ConfigEnvironment {
                        application: "test".to_string(),
                        profile: "dev".to_string(),
                        label: "master".to_string(),
                    },
                    operation: ChangeOperation::Create,
                    user: "test-user".to_string(),
                    timestamp: SystemTime::now(),
                    description: "创建配置".to_string(),
                    old_config: None,
                    new_config: Some(RustCloudConfig::default()),
                    details: HashMap::new(),
                },
            ])
        }

        async fn rollback(&self, environment: &ConfigEnvironment, version: &str, _user: &str) -> ConfigurationResult<()> {
            if self.should_fail {
                return Err(Box::new(MockServiceError::StorageError("模拟回滚失败".to_string())));
            }

            let key = self.make_key(environment).await;
            if let Some(mut data) = self.data.write().await.get_mut(&key) {
                data.version = version.to_string();
            }
            Ok(())
        }

        async fn initialize(&self) -> ConfigurationResult<()> {
            if self.should_fail {
                return Err(Box::new(MockServiceError::StorageError("模拟初始化失败".to_string())));
            }
            Ok(())
        }

        async fn health_check(&self) -> ConfigurationResult<bool> {
            Ok(!self.should_fail)
        }
    }

    // ============ Mock加密组件 ============

    pub struct AdvancedMockEncryption {
        algorithm: String,
        should_fail: bool,
    }

    impl AdvancedMockEncryption {
        pub fn new() -> Self {
            Self {
                algorithm: "AES-256-GCM".to_string(),
                should_fail: false,
            }
        }

        pub fn with_failure() -> Self {
            Self {
                algorithm: "AES-256-GCM".to_string(),
                should_fail: true,
            }
        }
    }

    #[async_trait]
    impl ConfigurationEncryption for AdvancedMockEncryption {
        async fn encrypt(&self, config: &mut RustCloudConfig) -> ConfigurationResult<()> {
            if self.should_fail {
                return Err(Box::new(MockServiceError::StorageError("加密失败".to_string())));
            }
            
            if !config.application.name.starts_with("encrypted:") {
                config.application.name = format!("encrypted:{}", config.application.name);
            }
            Ok(())
        }

        async fn decrypt(&self, config: &mut RustCloudConfig) -> ConfigurationResult<()> {
            if self.should_fail {
                return Err(Box::new(MockServiceError::StorageError("解密失败".to_string())));
            }
            
            if config.application.name.starts_with("encrypted:") {
                config.application.name = config.application.name[10..].to_string();
            }
            Ok(())
        }

        async fn encrypt_value(&self, value: &str) -> ConfigurationResult<String> {
            if self.should_fail {
                return Err(Box::new(MockServiceError::StorageError("值加密失败".to_string())));
            }
            Ok(format!("{}:{}", self.algorithm, value))
        }

        async fn decrypt_value(&self, encrypted_value: &str) -> ConfigurationResult<String> {
            if self.should_fail {
                return Err(Box::new(MockServiceError::StorageError("值解密失败".to_string())));
            }
            
            if let Some(pos) = encrypted_value.find(':') {
                Ok(encrypted_value[pos + 1..].to_string())
            } else {
                Ok(encrypted_value.to_string())
            }
        }

        fn is_encrypted(&self, value: &str) -> bool {
            value.starts_with(&format!("{}:", self.algorithm))
        }

        fn algorithm_name(&self) -> &str {
            &self.algorithm
        }
    }

    // ============ 测试用例 ============

    #[tokio::test]
    async fn test_advanced_mock_storage_operations() {
        let storage = AdvancedMockStorage::new();
        
        let environment = ConfigEnvironment {
            application: "test-app".to_string(),
            profile: "dev".to_string(),
            label: "master".to_string(),
        };

        // 测试不存在的配置
        let result = storage.load(&environment).await;
        assert!(result.is_err());

        // 添加测试数据
        storage.add_test_data(environment.clone(), RustCloudConfig::default()).await;

        // 测试加载配置
        let result = storage.load(&environment).await;
        assert!(result.is_ok());

        let data = result.unwrap();
        assert_eq!(data.environment.application, "test-app");
        assert_eq!(data.version, "v1.0.0");

        // 测试保存配置
        let save_result = storage.save(&data, "test-user").await;
        assert!(save_result.is_ok());
        assert_eq!(save_result.unwrap(), "v1.0.1");

        // 测试历史记录
        let history = storage.get_history(&environment).await.unwrap();
        assert_eq!(history.len(), 1);
        assert_eq!(history[0].operation, ChangeOperation::Create);

        // 测试健康检查
        assert!(storage.health_check().await.unwrap());

        // 测试删除配置
        storage.delete(&environment, "test-user").await.unwrap();
    }

    #[tokio::test]
    async fn test_advanced_mock_storage_failure() {
        let storage = AdvancedMockStorage::with_failure();
        
        let environment = ConfigEnvironment {
            application: "test-app".to_string(),
            profile: "dev".to_string(),
            label: "master".to_string(),
        };

        // 所有操作都应该失败
        assert!(storage.load(&environment).await.is_err());
        assert!(storage.initialize().await.is_err());
        assert!(!storage.health_check().await.unwrap());
    }

    #[tokio::test]
    async fn test_advanced_mock_encryption() {
        let encryption = AdvancedMockEncryption::new();
        
        // 测试算法名称
        assert_eq!(encryption.algorithm_name(), "AES-256-GCM");

        // 测试值加密解密
        let original_value = "sensitive-data";
        let encrypted = encryption.encrypt_value(original_value).await.unwrap();
        assert!(encrypted.starts_with("AES-256-GCM:"));
        assert!(encryption.is_encrypted(&encrypted));

        let decrypted = encryption.decrypt_value(&encrypted).await.unwrap();
        assert_eq!(decrypted, original_value);

        // 测试配置加密解密
        let mut config = RustCloudConfig::default();
        config.application.name = "test-app".to_string();
        
        encryption.encrypt(&mut config).await.unwrap();
        assert!(config.application.name.starts_with("encrypted:"));

        encryption.decrypt(&mut config).await.unwrap();
        assert_eq!(config.application.name, "test-app");
    }

    #[tokio::test]
    async fn test_advanced_mock_encryption_failure() {
        let encryption = AdvancedMockEncryption::with_failure();
        
        let mut config = RustCloudConfig::default();
        
        // 所有操作都应该失败
        assert!(encryption.encrypt(&mut config).await.is_err());
        assert!(encryption.decrypt(&mut config).await.is_err());
        assert!(encryption.encrypt_value("test").await.is_err());
        assert!(encryption.decrypt_value("test").await.is_err());
    }

    #[tokio::test]
    async fn test_integration_storage_and_encryption() {
        let storage = AdvancedMockStorage::new();
        let encryption = AdvancedMockEncryption::new();
        
        let environment = ConfigEnvironment {
            application: "integration-test".to_string(),
            profile: "prod".to_string(),
            label: "v1.0".to_string(),
        };

        // 创建配置
        let mut config = RustCloudConfig::default();
        config.application.name = "integration-app".to_string();

        // 加密配置
        encryption.encrypt(&mut config).await.unwrap();
        assert!(config.application.name.starts_with("encrypted:"));

        // 存储加密配置
        let data = ConfigurationData {
            environment: environment.clone(),
            config: config.clone(),
            version: "v1.0.0".to_string(),
            last_modified: SystemTime::now(),
            source: "integration-test".to_string(),
            properties: HashMap::new(),
        };

        storage.save(&data, "integration-user").await.unwrap();

        // 从存储加载
        let loaded_data = storage.load(&environment).await.unwrap();
        let mut loaded_config = loaded_data.config;

        // 解密配置
        encryption.decrypt(&mut loaded_config).await.unwrap();
        assert_eq!(loaded_config.application.name, "integration-app");
    }

    #[tokio::test]
    async fn test_concurrent_storage_operations() {
        let storage = Arc::new(AdvancedMockStorage::new());
        let mut handles = vec![];

        // 并发保存多个配置
        for i in 0..10 {
            let storage_clone = storage.clone();
            let handle = tokio::spawn(async move {
                let environment = ConfigEnvironment {
                    application: format!("app-{}", i),
                    profile: "dev".to_string(),
                    label: "master".to_string(),
                };

                let data = ConfigurationData {
                    environment,
                    config: RustCloudConfig::default(),
                    version: "v1.0.0".to_string(),
                    last_modified: SystemTime::now(),
                    source: "concurrent-test".to_string(),
                    properties: HashMap::new(),
                };

                storage_clone.save(&data, "concurrent-user").await
            });

            handles.push(handle);
        }

        // 等待所有任务完成
        for handle in handles {
            let result = handle.await.unwrap();
            assert!(result.is_ok());
        }
    }
}